/*
//   Copyright 2008 Dear Soft(http://dear-soft.com)
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
 */

package com.dear.soft.components.properties;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.dear.soft.components.properties.renderers.Reference;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.sun.imageio.plugins.common.ImageUtil;

public class PropertiesPanel extends JPanel {
	private static final long serialVersionUID = 1L;
	private final static CellConstraints cc = new CellConstraints();

	private PropertiesTable properties;
	private JPanel tools;
	private JPanel description;
	private PropertiesTableModel model;
	private JLabel descriptionArea;
	private JLabel titleLabel;
	private String title = "Properties";
	private JPanel titlePane;
	private String descriptionText;
	private JToggleButton copyToClipboard;

	public PropertiesPanel(PropertiesTableModel model) {
		super();
		this.model = model;
		initializeLayout();
	}

	public PropertiesPanel() {
		this(new PropertiesTableModel());
	}

	public void setTitle(String title) {
		this.title = title;
		if (titleLabel != null) {
			titleLabel.setText(this.title);
		}
	}

	private void initializeLayout() {
		setLayout(new FormLayout("2dlu,120dlu:grow,2dlu",
				"p,2dlu,p,3dlu,p:grow,20dlu:grow,2dlu,p,1dlu,10dlu:grow,2dlu"));
		;
		properties = new PropertiesTable();
		properties.setModel(model);
		properties.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		properties.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {
					public void valueChanged(ListSelectionEvent e) {
						updateDescription();
					}
				});

		add(getTitlePanel(), cc.xywh(1, 1, 3, 1, "f,f"));
		add(getToolsPanel(), cc.xywh(2, 3, 1, 1, "f,f"));
		add(new JScrollPane(properties), cc.xywh(2, 5, 1, 2, "f,f"));
		JPanel panel = new JPanel(new FormLayout("p:grow,10:grow,p", "p"));
		panel.add(new JLabel("<html><b> Description:</b></html>"), cc.xy(1, 1,
				"f,f"));
		panel.add(getCopyToClipboard(), cc.xy(3, 1, "f,f"));
		add(panel, cc.xy(2, 8, "f,f"));
		add(getDescriptionPanel(), cc.xywh(2, 10, 1, 1, "f,f"));
	}

	private JPanel getTitlePanel() {
		if (titlePane != null) {
			return titlePane;
		}
		titleLabel = new JLabel(title);
		titlePane = new JPanel(new FormLayout("1dlu, p:grow", "p"));
		titlePane.setOpaque(true);
		titlePane.setBackground(SystemColor.activeCaption);
		titleLabel.setForeground(SystemColor.activeCaptionText);
		titlePane.add(titleLabel, cc.xy(2, 1, "l,f"));
		return titlePane;
	}

	protected void updateDescription() {
		int index = properties.getSelectedRow();
		if (index >= 0) {
			Reference<?> ref = (Reference<?>) properties.getValueAt(index, 0);
			Object obj = ref.getRef();
			if (obj instanceof Category) {
				setDecription((Category) obj);
			}
			if (obj instanceof PropertyDescriptor) {
				setDecription((PropertyDescriptor) obj);
			}
		}

	}

	private void setDecription(Category cat) {
		setDescriptionText(cat.getDescription());
	}

	private void setDecription(PropertyDescriptor prop) {
		setDescriptionText(prop.getDescription());
	}

	private void setDescriptionText(String desc) {
		this.descriptionText = desc;
		descriptionArea.setText("<html><table border=0><tr><td>"
				+ desc.replaceAll("\n", "<br>") + "</td></td></table><html>");
	}

	private JPanel getDescriptionPanel() {
		if (description != null) {
			return description;
		}
		description = new JPanel(new FormLayout("p:grow", "1dlu,p:grow,1dlu"));
		descriptionArea = new JLabel();
		descriptionArea.setPreferredSize(new Dimension(150, 20));
		descriptionArea.setMinimumSize(new Dimension(150, 20));
		descriptionArea.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		descriptionArea.setVerticalAlignment(SwingConstants.TOP);
		descriptionArea.setHorizontalAlignment(SwingConstants.LEFT);
		descriptionArea.setOpaque(true);
		descriptionArea.setBackground(new Color(255, 255, 225));
		descriptionArea.setFont(descriptionArea.getFont().deriveFont(10.0f));

		description.add(descriptionArea, cc.xy(1, 2, "f,f"));
		return description;
	}

	private JToggleButton getCopyToClipboard() {
		if (copyToClipboard != null) {
			return copyToClipboard;
		}

		copyToClipboard = new JToggleButton(
				new ImageIcon(
						ImageUtil.class
								.getResource("/com/dear/soft/components/properties/res/copytoclipboard.png")));
		setButtonSize(copyToClipboard);
		copyToClipboard.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (copyToClipboard.isSelected()) {
					copyToClipboard.setSelected(false);
					copyDescription();
				}
			}
		});
		return copyToClipboard;
	}

	protected void copyDescription() {
		if (descriptionText != null && descriptionText.trim().length() > 0) {
			Clipboard clipboard = Toolkit.getDefaultToolkit()
					.getSystemClipboard();
			StringSelection stringSelection = new StringSelection(
					descriptionText);
			clipboard.setContents(stringSelection, new ClipboardOwner() {
				public void lostOwnership(Clipboard clipboard,
						Transferable contents) {
				}
			});
		}

	}

	private JPanel getToolsPanel() {
		if (tools != null) {
			return tools;
		}
		tools = new JPanel(new FormLayout(
				"0px,p,2dlu,p,2dlu,p,2dlu,p,10dlu:grow", "p"));
		final JToggleButton textMode = new JToggleButton(
				new ImageIcon(
						ImageUtil.class
								.getResource("/com/dear/soft/components/properties/res/alpha_mode.gif")));
		setButtonSize(textMode);
		textMode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (textMode.isSelected()) {
					textMode.setSelected(false);
					properties.setFlatMode(true);
				}
			}
		});

		final JToggleButton treeModel = new JToggleButton(
				new ImageIcon(
						ImageUtil.class
								.getResource("/com/dear/soft/components/properties/res/extensions.gif")));
		setButtonSize(treeModel);
		treeModel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (treeModel.isSelected()) {
					treeModel.setSelected(false);
					properties.setFlatMode(false);
				}
			}
		});

		final JToggleButton collapseall = new JToggleButton(
				new ImageIcon(
						ImageUtil.class
								.getResource("/com/dear/soft/components/properties/res/collapseall.gif")));
		setButtonSize(collapseall);
		collapseall.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (collapseall.isSelected()) {
					collapseall.setSelected(false);
					properties.collapse();
				}
			}
		});

		final JToggleButton expandall = new JToggleButton(
				new ImageIcon(
						ImageUtil.class
								.getResource("/com/dear/soft/components/properties/res/expandall.gif")));
		setButtonSize(expandall);
		expandall.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (expandall.isSelected()) {
					expandall.setSelected(false);
					properties.expand();
				}
			}
		});

		tools.add(textMode, cc.xy(2, 1, "f,f"));
		tools.add(treeModel, cc.xy(4, 1, "f,f"));
		tools.add(expandall, cc.xy(6, 1, "f,f"));
		tools.add(collapseall, cc.xy(8, 1, "f,f"));
		return tools;

	}

	private void setButtonSize(final JToggleButton textMode) {
		textMode.setSize(new Dimension(20, 20));
		textMode.setPreferredSize(new Dimension(20, 20));
		textMode.setMaximumSize(new Dimension(20, 20));
	}

	public void setModel(PropertiesTableModel model) {
		this.model = model;
		properties.setModel(model);
	}

}
